$$HEADER$$
<h3>Using OpenOCD</h3>
<p>This section presents <a  href="http://openocd.berlios.de">OpenOCD</a>, a tool used to program <b>eLua</b> on some of its targets. 
If you'd rather skip the long and boring OpenOCD introduction and
skip directly to the OpenOCD script downloads, use the links below.</p>

<ul>
  <li><a href="#str9files">Configuration files for STR9-comStick</a></li>
  <li><a href="#stre912files">Configuration files for STR-E912</a></li>
  <li><a href="#lpc2888files">Configuration files for LPC2888</a></li>
  <li><a href="#str7files">Configuration files for STR7</a></li>
</ul>

<h2>About OpenOCD</h2>

<p><a  href="http://openocd.berlios.de">OpenOCD</a> is an open source tool that can be used to connect to a CPU's 
<a  href="http://en.wikipedia.org/wiki/JTAG">JTAG</a>
interface. Using OpenOCD and a physical JTAG connection allows you to
burn the on-chip flash memory of your CPU (or to load your code
directly to RAM), to read the internal CPU memory (Flash/RAM) and to
use <a  href="http://sourceware.org/gdb/">gdb</a> or other debuggers to debug your code.
Needless to say, this is a very handy tool (and especially handy if
your CPU happens to be built around an ARM core, since in this case you
can be almost certain that it has a JTAG interface that you can use).
That said, if your only goal is to burn your firmware, my personal
suggestion is to avoid using OpenOCD if possible. It has quite a steep
learning curve, because it is a command line tool that uses
configuration files with lots of different parameters, and this takes a
while to get used to. Worse, I feel that it is not very well
docummented. The project's wiki does give a few good pointers about all
the configuration parameters, and there are some good OpenOCD tutorials
out there, but none of them tells the whole story. And the syntax (and
even some commands) seems to change between releases, which
makes things even more confusing. This is why I generally choose to use
a different firmware burning tool when available, and resort to OpenOCD
only for targets that lack a proper firmware burning tool. If you need
to debug your code, however, you probably want to use OpenOCD, since
the alternatives aren't cheap.
To summarize, you can forget about OpenOCD when:</p>

<ul>
  <li>your CPU manufacturer provides a special tool for
firmware burning. This is quite often the case, but more often that not
the aforementioned tools work only in Windows.</li>
  <li>you must debug your code, but you have a good intuition about where the
problem is located. In this case, simply connecting a LED to a PIO port
and turning it on and off from different parts of your code until you
figure out exactly what's the problem can work wonders. I can't
remember when was the last time I used gdb for debugging, since "LED
debugging" was all I needed. </li>
</ul>

<p>On the other hand, you should probably use OpenOCD when:</p>

<ul>
  <li>your CPU manufacturer doesn't provide a special tool for firmware burning (or it does, but it's not what you need).</li>
  <li>you're using Linux, MacOS or another OS that is not supported by the firmware burning tool.</li>
  <li>you need to do some serious debugging in order to understand what's wrong with your application.</li>
</ul>

<p>If you decided that you don't need OpenOCD after all, now it's a
good time to navigate away from this page and save yourself from some
possible symptoms of headache. If you need OpenOCD, read on, I'll try
to make this as painless as possible. However, don't expect this to be
a full tutorial on OpenOCD, because it's not; my intention is to give
you just enough data to use OpenOCD for burning <b>eLua</b> on your board.
Because of this, I won't be covering debugging with OpenOCD here, just
firmware burning. And, before we begin, please read and understand the
next paragraph.</p>

<h2 style="background-color: orangered;">Disclaimer</h2>

<p>Using OpenOCD improperly may force your CPU to behave
unexpectedly. While physically damaging your CPU as a result of using
OpenOCD is very hard to accomplish, you might end up with a locked
chip, or you might erase a memory area that was not supposed to be
erased, you might even disable the JTAG interface on your chip (thus
rendering it unusable). If you modify the configuration scripts that
I'm going to provide, make sure that you know what you're doing. Also,
I'm not at all an OpenOCD expert, so my configuration scripts might
have errors, even though I tested them. In short, this tutorial comes
without any guarantees whatsoever.</p>

<h2>Getting OpenOCD</h2>

<p>If you're on Windows, the best way to get OpenOCD already compiled and ready to run is to 
visit the <a  href="http://www.yagarto.de/">Yagarto home page</a>.
They provide a very nice OpenOCD installer, and they seem to keep up
with OpenOCD progress (the versions on the Yagarto site are not
"bleeding edge", but there are quite fresh nevertheless). If you're on
Linux, you can always use apt-get or your distribution-specific package
manager:</p>

<pre><code>$ sudo apt-get install openocd</code></pre>

<p>There is a catch here though: the OpenOCD version that I get from
apt-get is dated 2007-09-05, while the Yagarto OpenOCD version is from
2008-06-19. Since I'm using OpenOCD from Windows (because Ubuntu 8.04
doesn't seem to handle my USB-to-JTAG adapters very well), my
instructions are relevant to the Yagarto version. As mentioned in the
introduction, the meaning and parameters of different commands might
change between OpenOCD version, so if you want to use the Yagarto
version on your non Windows system, you'll have to build it from source
(see below).</p>
<p>The main resource on how to build OpenOCD from source is the <a  href="http://openfacts.berlios.de/index-en.phtml?title=Building_OpenOCD">OpenOCD build page</a> 
from the OpenOCD wiki. Also, a very good tutorial can be found <a  href="http://forum.sparkfun.com/viewtopic.php?t=11221">here</a>.
I'm not going to provide step by step build instructions, since the two
links that I mentioned cover this very well, and the build process is
relatively straightforward. However, since both tutorials describe how
to build the bleeding edge version of OpenOCD, you'll need a slight
modification do build the Yagarto version instead. The modification is
in the SVN checkout step. Replace this step:</p>

<pre><code>$ svn checkout svn://svn.berlios.de/openocd/trunk</code></pre>

<p>with this step ('717' is the SVN revision of the Yagarto OpenOCD build):</p>

<pre><code>$ svn checkout <b>-r 717</b> svn://svn.berlios.de/openocd/trunk</code></pre>


<p>Follow the rest of the build instructions, and in the end you should have a working OpenOCD.</p>
<h2>Supported targets</h2>

<p>I couldn't find a good list of the targets that are
supported by OpenOCD. So, if you want to check if your particular CPU
is supported by OpenOCD, I recommend getting the latest sources (as
described in the previous section) and listing the
trunk/src/target/target directory:</p>

<pre><code>$ ls trunk/src/target/target
at91eb40a.cfg
at91r40008.cfg
....
str9comstick.cfg
....
</code></pre>


<p>If this listing has something that looks like your CPU name, you're lucky. OpenOCD has support for LPC from NXP, AT91SAM cfrom Atmel, STR7/STR9 from ST, and many others.</p>

<h2>Using OpenOCD</h2>

<p>To use OpenOCD, you'll need:</p>

<ul>
  <li>the OpenOCD executable, as described above</li>
  <li>a board with a JTAG interface</li>
  <li>a JTAG adapter</li>
</ul>

<p>In some cases, your CPU board might provide a built in JTAG adapter. For example, 
my <a  href="http://www.luminarymicro.com/products/lm3s8962_can_ethernet_evaluation_kit.html">LM3S8962</a>
board provides both an USB-to-JTAG and an USB-to-serial converter built
on board, switching between them automagically. The same is true for my
<a  href="http://www.hitex.com/index.php?id=383">STR9-comStick</a>. 
On the other hand, my <a  href="http://www.olimex.com/dev/sam7-ex256.html">SAM7-EX256</a> board has only a JTAG connector, I need a separate JTAG adapter to connect to it. 
I'm using <a  href="http://www.olimex.com/dev/arm-usb-tiny.html">ARM-USB-TINY</a> from Olimex, but there are other affordable USB-to-JTAG adapters out there, 
like the <a  href="http://www.amontec.com/jtagkey-tiny.shtml">Amontec JTAGKey-Tiny</a>. Not to mention that you can 
<a  href="http://www.hs-augsburg.de/%7Ehhoegl/proj/usbjtag/usbjtag.html">build your own</a>. Although USB is my interface of choice, you'll find JTAG adapters for
PC LPT ports too. The good news is that once you buy a JTAG adapter,
chances are that it will work with many boards with different CPUs,
since the JTAG connector layout is standardized and the JTAG adapters
are generally able to work with different voltages.</p>
<p>To actually use OpenOCD, the next thing you'll need is a configuration file. The
configuration file is the one that lets OpenOCD know about your setup,
such as:</p>
<ul>
  <li>the kind of JTAG interface that you're using.</li>
  <li>the actual hardware platform you're using (ATM7TDMI, ARM966 and so on).</li>
  <li>the memory configuration of your CPU (flash banks).</li>
  <li>the script used to program the flash memory.</li>
</ul>


<p>Presenting a list of all the possible configuration options and
their meaning is way beside the scope of this document, so I'm not
going to do it, I'll give an example instead. I'm going
to use parts of my STR9-comStick configuration file (comstick.cfg)
adapted from the OpenOCD distribution and from other examples (don't
worry, I'll provide full download links for this file later on). First
we need to tell OpenOCD that we're using a the STR9-comStick
USB-to-JTAG adapter:</p>

<pre><code>interface ft2232
ft2232_device_desc "STR9-comStick A"
ft2232_layout comstick
ft2232_vid_pid 0x0640 0x002C
jtag_speed 4
jtag_nsrst_delay 100
jtag_ntrst_delay 100
</code></pre>


<p>Also, OpenOCD needs to know what's our target and its memory layout:</p>

<pre><code>target arm966e little run_and_init 1 arm966e
run_and_halt_time 0 50

working_area 0 0x50000000 32768 nobackup

flash bank str9x 0x00000000 0x00080000 0 0 0
flash bank str9x 0x00080000 0x00008000 0 0 0</code></pre>


<p>This tells OpenOCD that our target is an ARM966-E running in little
endian mode, with two flash memory banks, one that starts at 0x0 and
it's 0x80000 bytes in size, and another one that starts at 0x80000 and
it's 0x8000 bytes in size. Finally, OpenOCD must know what's the name
of our script file (this is the file that is used to physically program
the CPU memory):</p>

<pre><code>#Script used for FLASH programming
target_script 0 reset str91x_flashprogram.script</code></pre>


<p>The contents of the str91x_flashprogram.script is very target-dependent:</p>

<pre><code>wait_halt
str9x flash_config 0 4 2 0 0x80000
flash protect 0 0 7 off
flash erase_sector 0 0 7
flash write_bank 0 main.bin 0
reset run
sleep 10
shutdown</code></pre>


<p>I'm not even going to attempt to explain this one :) Basically it
unprotects the flash, erases it, writes the contents of "main.bin" to
flash, and then resets the CPU. If you need to flash a file with a
different name, the only thing you need to modify is the "main.bin" in
the "flash write_bank" line.</p>
<p>To use all this, you need to tell OpenOCD to use our configuration file:</p>

<pre><code>openocd-ftd2xx -f comstick.cfg</code></pre>


<p>(<b>note</b>: under Windows, the OpenOCD executable name is often
"openocd-ftd2xx". Under Linux it's simply "openocd". Replace it with
the actualy name with your executable).</p>
<p>That's it for your OpenOCD crash course. I realise that there's much
more to learn, so here's a list of links with much better information
on the subject:</p>

<ul>
  <li><a  href="http://www.hs-augsburg.de/%7Ehhoegl/proj/openocd/oocd-quickref.pdf">OpenOCD quick reference</a> card. (slightly outdated)</li>
  <li><a  href="http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_scripts">OpenOCD configuration examples</a> from the official OpenOCD wiki.</li>
  <li>An excellent page about using <a  href="http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html">OpenOCD with ARM controllers</a>, with lots 
  of real life examples.</li>
  <li>An interesting <a  href="http://forum.sparkfun.com/viewtopic.php?p=42079">topic on the SparkFun forum</a> about STR9 and OpenOCD.</li>
</ul>


<a name="str9files" /><h2>Configuration files for STR9-comStick</h2>

<p>Download them below:</p>

<ul>
  <li><a href="http://elua.berlios.de/other/comstick.cfg">comstick.cfg</a></li>
  <li><a href="http://elua.berlios.de/other/str91x_flashprogram.script">str91x_flashprogram.script</a></li>
  <li><a href="http://elua.berlios.de/other/comrst.cfg">comrst.cfg</a></li>
  <li><a href="http://elua.berlios.de/other/str91x_reset.script">str91x_reset.script</a></li>
</ul>

<p>For STR9 I'm using the Yagarto OpenOCD build for Windows (repository
version 717, as described at the beginning of this tutorial).The <b>comstick.cfg</b> configuration file is for programming the
STR9-comStick. <b>comrst.cfg</b> is for resetting it. The comStick has a very
interesting habit: after you power it (via USB) it does not start
executing the code from the internal flash, you need to execute OpenOCD
with the comreset.cfg script to start it. <b>comrst.cfg</b> does exactly what
it says: executes a CPU reset (since the board doesn't have a RESET
button). This is a very peculiar behavior, and I'm not sure if it's
generic or it's only relevant to my particular comStick. I suspect that
the CPU RESET line isn't properly handled by the on-board USB-to-JTAG
converter, and the only solution I have for this is to execute this
script everytime you power the board and everytime you need to do a
RESET. To use the programming script, invoke the OpenOCD executable like this:</p>

<pre><code>openocd-ftd2xx -f comstick.cfg</code></pre>

<p>(<b>note</b>: under Windows, the OpenOCD executable name is often
"openocd-ftd2xx". Under Linux it's simply "openocd". Replace it with
the actualy name with your executable).</p>

<p>Also, be sure to modify <b>str91x_flashprogram.script</b> if your image name is
not <b>main.bin</b></p>

<a name="stre912files" /><h2>Configuration files for STR-E912 (Olimex)</h2>

<p>Download them below:</p>

<ul>
  <li><a href="http://elua.berlios.de/other/str-e912.cfg">str-e912.cfg</a></li>
  <li><a href="http://elua.berlios.de/other/str91x_flashprogram.script">str91x_flashprogram.script</a></li>
</ul>

<p>For the <a href="http://www.olimex.com/dev/str-e912.html">STR-E912 board</a> I'm using the Yagarto OpenOCD build for Windows (repository
version 717, as described at the beginning of this tutorial). As this board doesn't have a built-in USB to JTAG adapter, an external one
is needed. The one used by the <b>str-e912.cfg</b> script is the <a href="http://olimex.com/dev/arm-usb-ocd.html">ARM-USB-OCD</a> adapter (also from Olimex).
The <b>str-e912.cfg</b> configuration file is for programming the board. To use the programming script, invoke the OpenOCD executable like this:</p>

<pre><code>openocd-ftd2xx -f str-e912.cfg</code></pre>

<p>(<b>note</b>: under Windows, the OpenOCD executable name is often
"openocd-ftd2xx". Under Linux it's simply "openocd". Replace it with
the actualy name with your executable).</p>

<p>Also, be sure to modify <b>str91x_flashprogram.script</b> if your image name is
not <b>main.bin</b></p>


<a name="lpc2888files" /><h2>Configuration files for LPC2888</h2>

<p>LPC2888 is quite a different animal. I couldn't find any "official"
LPC2888 configuration file for OpenOCD, so I had to learn how to write
my own. It works, but I suspect it can be improved. This time, the
configuration file applies to the latest (SVN) version of OpenOCD, so
use this tutorial to understand how to get the latest OpenOCD sources
and how to compile them (this section is based on version 922 of the
OpenOCD repository). Then use the next file to burn your binary image
to the chip:</p>

<p><a href="http://elua.berlios.de/other/lpc2888.cfg">lpc2888.cfg</a></p>

<p>If your image name is not <b>main.bin</b> edit the file and change the
corresponding line (<i>flash write_bank 0 main.bin 0</i>), then invoke openocd
like this:</p>

<pre><code>openocd -f lpc2888.cfg</code></pre>


<p>I'm using <a  href="http://www.olimex.com/dev/arm-usb-tiny.html">ARM-USB-TINY</a>
from Olimex, but it should be easy to use the script with any other
JTAG adapter (don't forget to change the script to match your adapter).</p>

<a name="str7files" /><h2>Configuration files for STR711FR2 (STR7 from ST)</h2>

<p>Download them below:</p>

<ul>
  <li><a href="http://elua.berlios.de/other/str7prg.cfg">str7prg.cfg</a></li>
  <li><a href="http://elua.berlios.de/other/str7_flashprogram.script">str7_flashprogram.script</a></li>
  <li><a href="http://elua.berlios.de/other/str7rst.cfg">str7rst.cfg</a></li>
  <li><a href="http://elua.berlios.de/other/str7_reset.script">str7_reset.script</a></li>
</ul>

<p>For STR7 I'm using the Yagarto OpenOCD build for Windows (repository
version 717, as described at the beginning of this tutorial). The
<b>str7prg.cfg</b> configuration file is for programming the STR9-comStick.
<b>str7rst.cfg</b> is for resetting it (you probably won't need this one). I'm using a STR711FR2 heard board from
<a  href="http://www.sctec.com.br/content/view/101/30/">ScTec</a> to
which I attached a few LEDs and a MAX3232 TTL to RS232 converter for
the serial communication. The board comes with its own JTAG adapter,
but it uses a parallel interface, and since my computer doesn't have
one, I used the <a  href="http://www.olimex.com/dev/arm-usb-tiny.html">ARM-USB-TINY</a> from Olimex. To use them, invoke the OpenOCD executable like this:</p>

<pre><code>openocd-ftd2xx -f str7prg.cfg</code></pre>


<p>(<b>note</b>: under Windows, the OpenOCD executable name is often
"openocd-ftd2xx". Under Linux it's simply "openocd". Replace it with
the actualy name with your executable).</p>
<p>Also, be sure to modify <b>str7_flashprogram.script</b> if your image name is
not <b>main.bin</b></p>
$$FOOTER$$

